package de.mhus.lib.vaadin;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.LinkedList;

import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.shared.MouseEventDetails.MouseButton;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Field;
import com.vaadin.ui.Table;
import com.vaadin.ui.TableFieldFactory;
import com.vaadin.ui.TextField;

import de.mhus.lib.core.MCast;
import de.mhus.lib.core.MCollection;

//TODO Implement handler for fields

public class MhuTable extends Table {
	
	protected Object editableId;
	private boolean tableEditable = false;

	{
		setTableFieldFactory(new TableFieldFactory() {
			
			@Override
			public Field<?> createField(Container container,
					Object itemId, Object propertyId, Component uiContext) {
				boolean editable = tableEditable && itemId.equals(editableId);
		        Field<?> f = null;
		        Class<?> type = container.getType(propertyId);
		        if (type == Boolean.class || type == boolean.class) {
		        	f = new CheckBox();
		        } else {
		        	f = new TextField();
		        }
		        f.setCaption(null);
		        f.setWidth("100%");
		        f.setReadOnly(!editable);
		        return f;
			}
		});
		
		addItemClickListener(new ItemClickListener() {
         @Override
         public void itemClick(ItemClickEvent event) {
        	 if (tableEditable && event.getButton() == MouseButton.LEFT && event.isDoubleClick()) {
		         editableId = event.getItemId();
		         addStyleName("editable");
		         setEditable(true);
	         } else if (event.getButton() == MouseButton.LEFT) {
		         editableId = null;
		         setEditable(false);
		         removeStyleName("editable");
	         }
         	}
         });
		
	}

	@Override
    protected Object getPropertyValue(Object rowId, Object colId, Property property) {
		if (property.getType() == Boolean.class || property.getType() == boolean.class) {
			return MCast.toboolean( property.getValue(), false) ? "\u2612" : "\u2610";
		}
        if (property.getType() == Date.class) {
        	if (property.getValue() == null || ((Date) property.getValue()).getTime() == 0) return "-";
            SimpleDateFormat df = new SimpleDateFormat();
            df.applyPattern("dd.MM.yyyy hh:mm:ss a");
            return df.format(((Date) property.getValue()).getTime());
        }
        return super.getPropertyValue(rowId, colId, property);
    }


	public boolean isTableEditable() {
		return tableEditable;
	}

	public void setTableEditable(boolean tableEditable) {
		this.tableEditable = tableEditable;
	}
	
	public Collection<?> getSelectedValues() {
		Object o = getValue();
		if (o == null) return new LinkedList<Object>();
		// this should not happen ...
		if (o instanceof Collection) return (Collection<?>)o;
		LinkedList<Object> out = new LinkedList<Object>();
		if (o instanceof Object[]) {
			MCollection.copyArray((Object[])o, out);
		} else
			out.add(o);
		return out;
	}
	
}
